import { userSession } from '@/api/user'
import { asyncRoutes, constantRoutes } from '@/router'

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(menuCodes, route) {
  // const { roles } = userInfo
  if (route.meta && route.meta.code) {
    return menuCodes.some(code => code === route.meta.code)
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, menuCodes) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(menuCodes, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, menuCodes)
      }
      res.push(tmp)
    }
  })
  return res
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = routes.concat(constantRoutes)
  },
  DEL_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = routes
  }
}

const actions = {
  generateRoutes({ commit, dispatch }, userInfo) {
    return new Promise(resolve => {
      userSession().then((resp) => {
        const { data } = resp
        const { menus } = data
        const menuCodes = []
        for (const item of menus) {
          const serviceCode = item.serveCode.toLowerCase().trim()
          if (serviceCode === process.env.VUE_APP_CODE) {
            const menuCode = item.menuCode.toLowerCase().trim()
            menuCodes.push(menuCode)
            // 加入父菜单
            const parentCode = menuCode.indexOf('-') > 0 ? menuCode.split('-')[0] : null
            if (parentCode && menuCodes.indexOf(parentCode) === -1) {
              menuCodes.push(parentCode)
            }
          }
        }
        const accessedRoutes = filterAsyncRoutes(asyncRoutes, menuCodes)
        // 更新用户信息
        const userInfo = {
          username: data.username,
          domainId: data.domainCode,
          projectId: data.projectId,
          projectName: data.projectName,
          id: data.id
        }
        dispatch('user/updateUser', userInfo, { root: true })
        commit('SET_ROUTES', accessedRoutes)
        resolve(accessedRoutes.concat(constantRoutes))
      })
    })
  },
  delRoutes({ commit }, roles) {
    return new Promise(resolve => {
      commit('DEL_ROUTES', roles)
      resolve({
        routes: [...state.routes],
        addRoutes: [...state.addRoutes]
      })
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
